// ==UserScript==
// @name         飞猪酒店跟价-辅助工具
// @namespace    http://tampermonkey.net/
// @version      2021-5-19
// @description  如名字描述。携程的也合并在里面了。这里只是获取房型的最低价，未能深入里面抓取具体价格 最后修改于 2021-5-19 10:41:22
// @author       ╮(╯▽╰)╭
// @match        http://localhost:3000/
// @match        http://localhost:9010/fgh
// @match        http://fp.lxfx.xyz:9010/fgh
// @match        http://fp.lxfx.xyz:9010/cth
// @match        https://hotel.fliggy.com/hotel_detail2.htm?*
// @match        https://hotel.fliggy.com/ota/hotel_room_detail.htm?hid=*
// @match        https://www.vipdlt.com/dltplatform/page/room/roomCalendar?hotel=*
// @match        https://hotels.ctrip.com/hotels/*.html*
// @match        *://erp.himudidi.com/platform_product_calendar/index/id/*/p_id/*.html
// @run-at       document-end
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @grant        GM_addValueChangeListener
// @grant        unsafeWindow
// @require      https://cdn.bootcss.com/zepto/1.2.0/zepto.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/vue/3.0.11/vue.global.prod.js
// ==/UserScript==
;

//     Zepto.js
//     (c) 2010-2016 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

;(function($){
  var zepto = $.zepto, oldQsa = zepto.qsa, oldMatches = zepto.matches

  function visible(elem){
    elem = $(elem)
    return !!(elem.width() || elem.height()) && elem.css("display") !== "none"
  }

  // Implements a subset from:
  // http://api.jquery.com/category/selectors/jquery-selector-extensions/
  //
  // Each filter function receives the current index, all nodes in the
  // considered set, and a value if there were parentheses. The value
  // of `this` is the node currently being considered. The function returns the
  // resulting node(s), null, or undefined.
  //
  // Complex selectors are not supported:
  //   li:has(label:contains("foo")) + li:has(label:contains("bar"))
  //   ul.inner:first > li
  var filters = $.expr[':'] = {
    visible:  function(){ if (visible(this)) return this },
    hidden:   function(){ if (!visible(this)) return this },
    selected: function(){ if (this.selected) return this },
    checked:  function(){ if (this.checked) return this },
    parent:   function(){ return this.parentNode },
    first:    function(idx){ if (idx === 0) return this },
    last:     function(idx, nodes){ if (idx === nodes.length - 1) return this },
    eq:       function(idx, _, value){ if (idx === value) return this },
    contains: function(idx, _, text){ if ($(this).text().indexOf(text) > -1) return this },
    has:      function(idx, _, sel){ if (zepto.qsa(this, sel).length) return this }
  }

  var filterRe = new RegExp('(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*'),
      childRe  = /^\s*>/,
      classTag = 'Zepto' + (+new Date())

  function process(sel, fn) {
    // quote the hash in `a[href^=#]` expression
    sel = sel.replace(/=#\]/g, '="#"]')
    var filter, arg, match = filterRe.exec(sel)
    if (match && match[2] in filters) {
      filter = filters[match[2]], arg = match[3]
      sel = match[1]
      if (arg) {
        var num = Number(arg)
        if (isNaN(num)) arg = arg.replace(/^["']|["']$/g, '')
        else arg = num
      }
    }
    return fn(sel, filter, arg)
  }

  zepto.qsa = function(node, selector) {
    return process(selector, function(sel, filter, arg){
      try {
        var taggedParent
        if (!sel && filter) sel = '*'
        else if (childRe.test(sel))
          // support "> *" child queries by tagging the parent node with a
          // unique class and prepending that classname onto the selector
          taggedParent = $(node).addClass(classTag), sel = '.'+classTag+' '+sel

        var nodes = oldQsa(node, sel)
      } catch(e) {
        console.error('error performing selector: %o', selector)
        throw e
      } finally {
        if (taggedParent) taggedParent.removeClass(classTag)
      }
      return !filter ? nodes :
        zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))
    })
  }

  zepto.matches = function(node, selector){
    return process(selector, function(sel, filter, arg){
      return (!sel || oldMatches(node, sel)) &&
        (!filter || filter.call(node, null, arg) === node)
    })
  }
})(Zepto)
const formatDate = (date, offset = 0) => {
  try {
    let t = new Date(new Date(date).getTime() + 86400000 * offset);
    return `${t.getFullYear()}-${(t.getMonth() + 1).toString().padStart(2, '0')}-${t.getDate().toString().padStart(2, '0')}`;
  } catch (error) { return '' }
}


const prevDay = ()=>{
  $("#J_CheckOutDate").val($("#J_CheckInDate").val())
  setTimeout(() => {
    $("#J_CheckInDate").val(formatDate($("#J_CheckInDate").val(), -1))
  }, 1000);
};
const nextDay = ()=>{
  $("#J_CheckOutDate").val(formatDate($("#J_CheckInDate").val(), 2))
  setTimeout(() => {
    $("#J_CheckInDate").val(formatDate($("#J_CheckInDate").val(), 1))
  }, 1000);
};

$("#J_ChangeRange").after('<button class="pi-btn pi-btn-primary pi-btn-sm" id="prevDay" type="submit">前一天</button><button class="pi-btn pi-btn-primary pi-btn-sm" id="nextDay" type="submit">下一天</button>');
$("#prevDay").on("click", prevDay);
$("#nextDay").on("click", nextDay);
if(location.href.includes("hotel.fliggy.com/hotel_detail2.htm")
  || location.href.match(/https:\/\/hotels.ctrip.com\/hotels\/\d{6,12}.html/)
){   // wrapper
  unsafeWindow.Vue = Vue;

  unsafeWindow.priceTable = {
    emits:['changeRoom'],
    props:{
      data: {
        type: Object, 
        default(){
          return{
            dates: [],
            prices: {},
            roomIds: []
          }
        }
      },
      matchedRooms: {type: Array, default(){return []}}
    },
    setup(props, ctx){
      const weekDay = (d)=>{ return new Date(d).getDay() }
      const gridTemplateRows = Vue.computed(()=>{ return `40px repeat(${props.data.roomIds.length}, 1fr)` })
      const calendarGridTemplateColumns = Vue.computed(()=>{return `repeat(${props.data.dates.length}, 46px)`})
      const getRoomDatePrice = (roomId, date)=>{
        try {
          return props.data.prices[roomId][date]
        } catch (error) { return '' }
      }
      const changeRoom = (roomId)=>{
        ctx.emit('changeRoom', {id: roomId, title: props.data.prices[roomId].title})
      }

      return {
        weekDay, 
        gridTemplateRows,
        calendarGridTemplateColumns,
        getRoomDatePrice,
        changeRoom
      }
    },
    template: `
      <div id="price-table">
        <div class="row-name" :style="{gridTemplateRows: gridTemplateRows}">
          <div data-content="房型"></div>
          <div
            v-for="roomId in data.roomIds"
            :data-content="data.prices[roomId].title"
            @click="changeRoom(roomId)"
            :class="[matchedRooms.includes(roomId) ? 'matched-room' : '']"
          ></div>
        </div>
        <div class="calendar" :style="{gridTemplateColumns: calendarGridTemplateColumns}">
          <!--依次为 日期、卖价、利润、成本、保存、重置 -->
          <div name="date" v-for="date in data.dates"  :style="{gridTemplateRows: gridTemplateRows}">
            <div
              :data-weekday="weekDay(date)"
              class="inline-date"
            >
              <b :data-content="date.slice(5)"></b>
              <b></b>
            </div>
            <div
              v-for="roomId in data.roomIds"
              :data-content="getRoomDatePrice(roomId, date)"
            ></div>
          </div>
        </div>
      </div>
    `,
  }

  GM_addStyle(`
    #price-table{
      font-size: 12px;
      display: grid;
      /* grid-template-columns: 100px calc(100% - 100px); */
      grid-template-columns: auto auto;
      background: #E0E0E0;
    }
    #price-table .inline-date{ 
      display: grid !important;
      grid-template-rows: 1fr 1fr;
    }
    #price-table [data-content]::before{
      content: attr(data-content)
    }
    #price-table .row-name,
    #price-table .calendar>div{
      display: inline-grid;
      grid-gap: 2px;
      /* grid-template-rows: repeat(6, 1fr); */
      white-space: nowrap;
      /* padding-bottom: 12px;  滚动条占位*/
    }
    #price-table .row-name>div,
    #price-table .calendar>div>div{
      background: #fff;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      white-space: pre-line;
      cursor: pointer;
    }
    #price-table .row-name>.matched-room{ background: #FFF8D0 }
    #price-table .row-name>div:hover,
    #price-table .calendar>div>div:hover{
      background: #F3F3F3;
    }
    #price-table .calendar{
      display: grid;
      grid-column-gap: 2px;
      /* grid-template-columns: repeat(60, 46px); */
      overflow-x: auto;
      overflow-y: hidden;
    }
    #price-table .profit-warning{
      background: pink !important;
      color: #EB3941;
    }
    #price-table .row-name{
      padding-right: 2px;
    }
    #price-table .selected{
      box-shadow: inset 0 0 2px 3px red
    }

    [data-weekday="0"] b:nth-child(2)::before{content: '周日'}
    [data-weekday="1"] b:nth-child(2)::before{content: '周一'}
    [data-weekday="2"] b:nth-child(2)::before{content: '周二'}
    [data-weekday="3"] b:nth-child(2)::before{content: '周三'}
    [data-weekday="4"] b:nth-child(2)::before{content: '周四'}
    [data-weekday="5"] b:nth-child(2)::before{content: '周五'}
    [data-weekday="6"] b:nth-child(2)::before{content: '周六'}
    [data-weekday="5"],
    [data-weekday="6"]{padding:1px;background:#ffcdd2 !important;}
  `)

} // wrapper
// 酒店售卖页面的相关功能
if(location.href.includes("hotel.fliggy.com/hotel_detail2.htm")){
  if(typeof Vue === "undefined"){ unsafeWindow.Vue = Vue; }

  const state = Vue.reactive({
    dates: [],
    roomIds: [],
    prices: {},
  })
  
  // 抓取所有的房型ID，返回一个ID数组
  const getRoomIds = ()=>{
    let idsArray = []
    $("#J_RoomList div[data-srtid]").each((index,elem)=>{
      idsArray.push($(elem).attr("data-srtid"))
    })
    return idsArray
  }
  // 在界面直接显示房型ID，方便建立项目的时候找到房型匹配的信息
  const showRoomsId = ()=>{
    $("#J_RoomList div[data-srtid]").each((index, elem)=>{
      $(`<b class="show-roomid">${$(elem).attr("data-srtid")}</b>`).insertBefore($(elem).find(".room-item-baseinfo.J_ExpandQuotedPrice"))
    })
  }
  
  // 标准房型信息, 获取并且更新 Tampermonkey 存储
  const getStandardRoomsInfo = ()=>{
    let data = {shid: $("#J_Shid").val(), rooms: []}
    $("#J_RoomList div[data-srtid]").each((index,elem)=>{
      data.rooms.push({
        id: $(elem).attr("data-srtid"),
        name: $(elem).find("span.item-title").text().trim()
      })
    })
    GM_setValue("standardRooms", {})
    GM_setValue("standardRooms", data)
    return data
  }

  // 存储售卖价格信息到 Tampermonkey 存储
  const saveSalePrices = ()=>{
    GM_setValue("salePrices", {})
    GM_setValue("salePrices", {
      name: cfg.hotelInfo.name, // 网页本身的数据,
      shid: $("#J_Shid").val(),
      data: state
    })
  }
  
  // 检查房型ID是否齐全，就是每次抓数据前先检查一次房型是否齐全,如果不齐全，就补全
  const checkRoomIds = ()=>{
    let ids = getRoomIds()
    if(ids.join() !== state.roomIds.join()){
      $(ids).each((index, id)=>{
        if(!state.roomIds.includes(id)){
          state.roomIds.push(id)
          state.prices[id] = {title: $(`div[data-srtid="${id}"]`).find("span.item-title").text().trim()}
        }
      })
    }
  }
  // 抓取1天的价格，放到 state 
  const get1DayPrices = ()=>{
    let date = $("#J_CheckInDate").val()
    if(!state.dates.includes(date)){
      state.dates.push(date)
      state.dates.sort()
    }
    let rooms = $("#J_RoomList div[data-srtid]")
    rooms.each((index,elem)=>{
      state.prices[$(elem).attr("data-srtid")][date] = parseInt($(elem).find(".room-price-wrapper").text().match(/[\d\.]{2,7}/g)[0])
    })
    Object.assign(state, {})
  }
  // 更新1天的价格，先检查房型ID，再抓取价格更新到 state 
  const updateDatePrices = ()=>{
    checkRoomIds()
    get1DayPrices()
    console.log(state, '==========')
  }

  
  GM_addStyle(`
    #getPricesApp{
      font-family: "微软雅黑" !important;
      position: fixed;
      top: 0;
      display: grid;
      grid-template-rows: calc(100% - 25px);
      min-width: 50;
      min-height: 30px;
      max-height: 350px;
      z-index: 99999;
    }
    .show-roomid{
      font-size: 20px !important;
    }
    #getPricesApp button{
      font-family: inherit;
      margin: 1px;
      border: 0;
      width: auto;
      white-space: nowrap;
      color: #fff;
      background-color: #63b8f0;
      border-color: #34a3ec;
      box-shadow: 0 2px 0 #34a3ec;
      padding: 6px 1em;
      font-size: 12px;
      line-height: 1;
      border-radius: 3px;
      cursor: pointer;
    }
    #getPricesApp button:hover{
      background-color: #34a3ec;
    }
  `)
  
  const htmlCode = `
    <div id="getPricesApp">
      <price-table :data="state" v-show="isShowPanel"></price-table>
      <div>
        <button @click="switchShowPanel">👀</button>
        <button @click="showRoomsId" v-show="isShowPanel">展示房型ID</button>
        <button @click="updateDatePrices" v-show="isShowPanel">获取价格</button>
        <button @click="getStandardRoomsInfo" v-show="isShowPanel">获取房型信息</button>
        <button @click="saveSalePrices" v-show="isShowPanel">保存价格</button>
      </div>
    </div>
  `;
  $("body").append(htmlCode);
  unsafeWindow.followPriceApp = Vue.createApp({
    components:{'price-table': priceTable},
    setup(){
      const isShowPanel = Vue.ref(GM_getValue("isShowPanel", false))
      const switchShowPanel = ()=>{
        GM_setValue("isShowPanel", !isShowPanel.value)
        isShowPanel.value = !isShowPanel.value
      }
      return {
        isShowPanel,
        switchShowPanel,
        state,
        showRoomsId,
        updateDatePrices,
        getStandardRoomsInfo,
        saveSalePrices,
      }
    }
  }).mount("#getPricesApp")

  // 不是Vue 元素的样式，具体价格的样式
  GM_addStyle(`
    tr.first>td.item-price div.promo-wrap::after{
      content: "抓";
      display: inline-flex;
      justify-content: center;
      align-items: center;
      height: 20px;
      background: #FFC900;
      padding: 3px 10px;
      margin-left: 15px;
      border-radius: 3px;
      cursor: pointer;
    }
  `)
  $("#J_RoomList").on("click", e=>{
    if(e.target.getAttribute("class").includes("promo-wrap")){
      console.log(e.target.textContent)
      let price = parseInt(e.target.children[0].textContent.match(/[\d\.]+/g)[0])
      let srtid = $(e.target).parents("div[data-srtid]").attr("data-srtid")
      let date = $("#J_CheckInDate").val()
      state.prices[srtid][date] = price
    }
  })

}

// 携程酒店售卖页面的相关功能
if(location.href.match(/https:\/\/hotels.ctrip.com\/hotels\/\d{6,12}.html/)){
  if(typeof Vue === "undefined"){ unsafeWindow.Vue = Vue; }

  const state = Vue.reactive({
    dates: [],
    roomIds: [],
    prices: {},
  })
  
  // 抓取所有的房型ID，返回一个ID数组
  const getRoomIds = ()=>{
    let idsArray = []
    $("#roomlist-baseroom-fit[class=roomlist-baseroom] div.roomlist-baseroom-card").each((index,elem)=>{
      idsArray.push($(elem).attr("id"))
    })
    return idsArray
  }
  // 在界面直接显示房型ID，方便建立项目的时候找到房型匹配的信息
  const showRoomsId = ()=>{
    $("#roomlist-baseroom-fit.roomlist-baseroom div.roomlist-baseroom-card").each((index, elem)=>{
      $(`<b class="show-roomid">${$(elem).attr("id")}</b>`).insertAfter($(elem).find("div.policy"))
    })
  }
  
  // 标准房型信息, 获取并且更新 Tampermonkey 存储
  const getStandardRoomsInfo = ()=>{
    let data = {
      // masterHotelId: location.href.match(/\d{6,12}\.html/g)[0].slice(0, -5),
      shid: location.href.match(/\d{6,12}\.html/g)[0].slice(0, -5),
      rooms: []
    }
    $("#roomlist-baseroom-fit[class=roomlist-baseroom] div.roomlist-baseroom-card").each((index,elem)=>{
      data.rooms.push({
        id: $(elem).attr("id"),
        name: $(elem).find("div.roomname").text()
      })
    })
    GM_setValue("standardRooms", {})
    GM_setValue("standardRooms", data)
    return data
  }

  // 存储售卖价格信息到 Tampermonkey 存储
  const saveSalePrices = ()=>{
    GM_setValue("salePrices", {})
    GM_setValue("salePrices", {
      name: $("#ibu-hotel-detail-head h1").text(), // 网页本身的数据,
      shid: location.href.match(/\d{6,12}\.html/g)[0].slice(0, -5),
      data: state
    })
  }
  
  // 检查房型ID是否齐全，就是每次抓数据前先检查一次房型是否齐全,如果不齐全，就补全
  const checkRoomIds = ()=>{
    let ids = getRoomIds()
    if(ids.join() !== state.roomIds.join()){
      $(ids).each((index, id)=>{
        if(!state.roomIds.includes(id)){
          state.roomIds.push(id)
          state.prices[id] = {title: $(`div.roomlist-baseroom-card[id="${id}"]`).find("div.roomname").text().trim()}
        }
      })
    }
  }
  // 抓取1天的价格，放到 state 
  const get1DayPrices = ()=>{
    let date = $("#detail-room-list .time-tab input").first().attr("data-key").replace(/\//g, "-")
    if(!state.dates.includes(date)){
      state.dates.push(date)
      state.dates.sort()
    }
    let rooms = $("#roomlist-baseroom-fit[class=roomlist-baseroom] div.roomlist-baseroom-card")
    rooms.each((index,elem)=>{
      // state.prices[$(elem).attr("id")][date] = parseInt($(elem).find(".saleroomlist div[ubt-roomid]:first-child #detail-real-price").text().replace(/[^\d\.]/g, ''))  // 之前这个是起作用的，不知怎么失效了
      state.prices[$(elem).attr("id")][date] = parseInt($(elem).find(".saleroomlist div[ubt-roomid]:first-child div.price").children().first().text().replace(/[^\d\.]/g, ''))
    })
    Object.assign(state, {})
  }
  // 更新1天的价格，先检查房型ID，再抓取价格更新到 state 
  const updateDatePrices = ()=>{
    checkRoomIds()
    get1DayPrices()
    addGrabPriceListener() //添加事件
  }

  
  GM_addStyle(`
    #getPricesApp{
      font-family: "微软雅黑" !important;
      position: fixed;
      top: 0;
      display: grid;
      grid-template-rows: calc(100% - 25px);
      min-width: 50;
      min-height: 30px;
      max-height: 350px;
      z-index: 99999;
    }
    .show-roomid{
      font-size: 20px !important;
    }
    #getPricesApp button{
      font-family: inherit;
      margin: 1px;
      border: 0;
      width: auto;
      white-space: nowrap;
      color: #fff;
      background-color: #63b8f0;
      border-color: #34a3ec;
      box-shadow: 0 2px 0 #34a3ec;
      padding: 6px 1em;
      font-size: 12px;
      line-height: 1;
      border-radius: 3px;
      cursor: pointer;
    }
    #getPricesApp button:hover{
      background-color: #34a3ec;
    }
  `)
  
  const htmlCode = `
    <div id="getPricesApp">
      <price-table :data="state" v-show="isShowPanel"></price-table>
      <div>
        <button @click="switchShowPanel">👀</button>
        <button @click="showRoomsId" v-show="isShowPanel">展示房型ID</button>
        <button @click="updateDatePrices" v-show="isShowPanel">获取价格</button>
        <button @click="getStandardRoomsInfo" v-show="isShowPanel">获取房型信息</button>
        <button @click="saveSalePrices" v-show="isShowPanel">保存价格</button>
      </div>
    </div>
  `;
  $("body").append(htmlCode);
  unsafeWindow.followPriceApp = Vue.createApp({
    components:{'price-table': priceTable},
    setup(){
      const isShowPanel = Vue.ref(GM_getValue("isShowPanel", false))
      const switchShowPanel = ()=>{
        GM_setValue("isShowPanel", !isShowPanel.value)
        isShowPanel.value = !isShowPanel.value
      }
      return {
        isShowPanel,
        switchShowPanel,
        state,
        showRoomsId,
        updateDatePrices,
        getStandardRoomsInfo,
        saveSalePrices,
      }
    }
  }).mount("#getPricesApp")


  const addGrabPriceListener = () => {
    // 添加style元素
    // 不是Vue 元素的样式，具体价格的样式
    if(!$("#grab-price").length){
      $("head").append("<style type='text/css' id='grab-price'></style>")
      $("#grab-price").html(`
        span.price-delete::after,
        div.price-display::after{
          content: "抓";
          display: inline-flex;
          justify-content: center;
          align-items: center;
          height: 20px;
          background: #FFC900;
          padding: 3px 10px;
          margin-left: 15px;
          border-radius: 3px;
          cursor: pointer;
        }`)
    }
    $("span.price-delete,div.price-display").on("click", e=>{
      if(e.target.getAttribute("class").includes("price")){
        let price = parseInt(e.target.textContent.replace(/[^\d\.]/g, ''))
        let srtid = $(e.target).parents("div.roomlist-baseroom-card").attr("id")
        let date = $("#detail-room-list .time-tab input").first().attr("data-key").replace(/\//g, "-")
        state.prices[srtid][date] = price
      }
    })
  }

}

// 跟价项目页面，相关的功能
// 比如 监听 adminRooms，standardRooms 等等 Tampermonkey 的变动 
// if(location.href == "http://localhost:3000/" || location.href == "http://localhost:9010/fgh"){
if(location.href == "http://fp.lxfx.xyz:9010/fgh" || location.href == "http://fp.lxfx.xyz:9010/cth"){
  unsafeWindow.GM_addValueChangeListener = GM_addValueChangeListener;
  unsafeWindow.GM_getValue = GM_getValue;
}

// 飞猪商家后台 相关功能
// 目前主要是 找到商家后台某酒店的房型ID，也是不用ajax,打开具体后台页面用jQuery抓数据，然后存储在 Tampermonkey 
if(location.href.includes("hotel.fliggy.com/ota/hotel_room_detail.htm")){


  // 商家后台房型信息, 获取并且更新 Tampermonkey 存储
  const getAdminRoomsInfo = ()=>{
    let data = {
      ahid: location.search.match(/hid=\d{10,16}/)[0].slice(4), // shid
      shid: location.search.match(/hid=\d{10,16}/)[0].slice(4), // shid
      platform: 'fgh',
      rooms: []
    }
    $("table.batch-dealer-table:contains(房价绑定)").find("tr").each((index,elem)=>{
      // 第一行是表头不处理,空行也不处理
      if(index && $(elem).find("td").length){
        let tds = $(elem).find("td")
        data.rooms.push({
          rid: tds[1].textContent.match(/\d{12,15}/g)[0],
          amuId: tds[1].textContent.match(/\(\d{5,8}\)/g)[0].slice(1,-1),
          name: $(tds[2]).find("b").text().trim()
        })
      }
    })
    GM_setValue("adminRooms", {})
    GM_setValue("adminRooms", data)
    return data
  }

  // 添加功能按钮
  GM_addStyle(`#getAdminRoomsInfo{z-index:99999;position:fixed;left: 5px;top:100px;}`)
  $("#header").append('<button id="getAdminRoomsInfo" class="pi-btn pi-btn-sm pi-btn-warning">房型信息</button>')
  $("#getAdminRoomsInfo").on("click", getAdminRoomsInfo)

}

// 携程商家后台  相关功能
if(location.href.includes("www.vipdlt.com/dltplatform/page/room/roomCalendar?hotel=")){
  // 商家后台房型信息, 获取并且更新 Tampermonkey 存储
  const getAdminRoomsInfo = () => {
    let data = {
      // subHotelId: $("input#hotelId").val(),
      // masterHotelId: $("#h3HotelLink a.ico-hotels-b2b.url-b2b").attr("href").match(/\d{6,12}/g)[0],
      ahid: $("input#hotelId").val(),
      shid: $("#h3HotelLink a.ico-hotels-b2b.url-b2b").attr("href").match(/\d{6,12}/g)[0],
      platform: 'cth',
      rooms:[]
    }
    $("#calendarTable tr.sale-room-tr").each((index, elem)=>{
      data.rooms.push({
        roomId: $(elem).attr("roomid"),
        basicRoomId: $(elem).attr("basicroomid"),
        name: $(elem).find("span[name=sproomname]").text()
      })
    })
    GM_setValue("adminRooms", {})
    GM_setValue("adminRooms", data)
    return data
  }
  // 添加功能按钮
  GM_addStyle(`#getAdminRoomsInfo{z-index:99999;position:fixed;left: 5px;top:100px;}`)
  $("body").append('<button id="getAdminRoomsInfo" class="btn-ini pi-btn-warning">房型信息</button>')
  $("#getAdminRoomsInfo").on("click", getAdminRoomsInfo)

}


// 价格日历 利润视图 功能，建议做在新版 阿目云
if(location.href.includes("erp.himudidi.com/platform_product_calendar/")){
  GM_addStyle(`
    [data-content*='利润：-']{
      font-size: 26px;
      background: pink !important;
      padding-top: 10px;
      padding-bottom: 10px;
    }
    [data-view]::before{
      content: attr(data-view);
      font-size: 26px;
      margin-right: 15px;
    }
  `)
  $("body").append("<style id='profit-view-style'></style>")
  let currentMonth =  ""
  let currentView = ""
  const calendarStore = {}
  // 把需要处理的数据梳理存储起来
  const storeData = ()=>{
    currentMonth =  $("#calendar h2").text()
    $("td.fc-day[data-date]").each((index, elem)=>{
      let child = $(elem).find("[data-content]")
      let content = child.length ? child.first().attr("data-content") : ""
      if(content){
        calendarStore[elem.dataset.date] = {
          sell: content.match(/售价：[\d\.]+/g)[0].slice(3),
          cost: content.match(/成本：[\d\.]+/g)[0].slice(3),
          profit: content.match(/利润：[\-\d\.]+/g)[0].slice(3),
          childElem: child // 保存元素，不用二次查找
        }
      }
    })
  }
  // 利润模式
  const profitView = ()=>{
    if(currentMonth != $("#calendar h2").text()){ storeData() }
    $.each(calendarStore, (index,item)=>{
      item.childElem.attr("data-view", item.profit)
      item.childElem.text("")
    })
    $("#profit-view-style").html("[data-view]::before{ color: #E9A326 !important;}")
    currentView = "profitView"
  }
  // 成本模式
  const costView = ()=>{
    if(currentMonth != $("#calendar h2").text()){ storeData() }
    $.each(calendarStore, (index,item)=>{
      item.childElem.attr("data-view", item.cost)
      item.childElem.text("")
    })
    $("#profit-view-style").html("[data-view]::before{ color: #FF5252 !important;}")
    currentView = "costView"
  }
  // 售价模式，就是恢复原状
  const sellView = ()=>{
    if(currentMonth != $("#calendar h2").text()){ storeData() }
    $.each(calendarStore, (index,item)=>{
      item.childElem.removeAttr("data-view")
      item.childElem.text(item.sell)
    })
    $("#profit-view-style").html("")
    currentView = ""
  }

  $("#calendar h2").after(`
    <button id="profit-view" class="btn btn-warning">利润</button>
    <button id="cost-view" class="btn btn-danger">成本</button>
    <button id="sell-view" class="btn btn-success">售价</button>
  `)
  $("#profit-view").on("click", profitView)
  $("#cost-view").on("click", costView)
  $("#sell-view").on("click", sellView)
  // 左右翻月份，如果有设定视图模式的话，自动执行
  $("#calendar div.fc-right, #calendar div.fc-left").on("click", ()=>{
    if(currentView){ 
      // 设为 400ms ,是考虑到 ajax 加载数据需要延时，同时体验又不至于太差
      setTimeout(() => {
        eval(`${currentView}()`)
      }, 400) }
  })

}

